package com.myGroup.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myGroup.dto.UserDTO;
import com.myGroup.dto.UserLoginDTO;
import com.myGroup.pojo.Activity;
import com.myGroup.pojo.R;
import com.myGroup.pojo.TakePart;
import com.myGroup.pojo.User;
import com.myGroup.service.UserService;
import com.myGroup.utils.JwtUtils;
import com.myGroup.utils.ThreadLocalUtil;
import com.myGroup.vo.UserLoginVO;
import io.swagger.annotations.*;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;

@RestController
@Slf4j
@Api(tags = "用户管理接口")
@RequestMapping("/admin/user")
public class UserController {
    @Autowired
    private UserService userService;

    @Autowired
    private HttpServletRequest request;



//    private Integer userId;

    /**
     * 管理员登录的接口
     *
     * @param userLoginDTO
     * @return
     */
    @ApiOperation(value = "管理员登录", notes = "后台管理员登录的接口")
    @PostMapping("/login")
    public R<UserLoginVO> login(@RequestBody UserLoginDTO userLoginDTO) {
        // 加密
        String password = userLoginDTO.getPassword();
//        password = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        log.info("加密后的：{}", password);

        // 查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName, userLoginDTO.getNickName());
        User user = userService.getOne(queryWrapper);

        // 校验
        if (user == null) {
            return R.error("用户不存在！");
        }
        if (!user.getPassword().equals(password)) {
            return R.error("密码错误！");
        }
        if (user.getStatus() == 0) {
            return R.error("用户已被禁用，请联系管理员");
        }
        if (!user.getJob().equals("1")) {
            return R.error("对不起，但您不是管理员！");
        }

        // 登录成功
        //自定义信息
        Map<String , Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getNickName());
        claims.put("name", user.getName());

        //使用JWT工具类，生成身份令牌
        String token = JwtUtils.generateJwt(claims);

        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setId(user.getId());
        userLoginVO.setNickName(user.getNickName());
        userLoginVO.setToken(token);

        // 给前端相应结果，把用户的token给前端，要求前端每次请求时带上token
        return R.success(userLoginVO);
    }

    /**
     * 管理员退出登录
     *
     * @return
     */
    @PostMapping("/logout")
    @ApiOperation(value = "管理员登出")
    public R<String> logout() {
        return R.success("退出成功！");
    }

    /**
     * 新增员工
     *
     * @param userDTO
     * @return
     */
    @ApiOperation("用户注册")
    @PostMapping()
    public R<String> save(@RequestBody UserDTO userDTO) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName, userDTO.getNickName());

        // 校验
        if (userService.getOne(queryWrapper) != null) {
            return R.error("这个用户名已经被用过了，请换一个吧");
        }

        User user = new User();
        BeanUtils.copyProperties(userDTO, user); // 拷贝
        // log.info(user.toString());

        // 操作service
        userService.save(user);

        // 给前端相应结果，把用户的token给前端，要求前端每次请求时带上token
        return R.success("恭喜您，注册成功！");
    }

    /**
     * 志愿者登录接口
     *
     * @param userLoginDTO
     * @return
     */
    @ApiOperation(value = "志愿者登录", notes = "志愿者登录的接口")
    @PostMapping("/userlogin")
    public R<UserLoginVO> userLogin(@RequestBody UserLoginDTO userLoginDTO) {
        // 加密
        String password = userLoginDTO.getPassword();
//        password = DigestUtils.md5DigestAsHex(password.getBytes(StandardCharsets.UTF_8));
        log.info("加密后的：{}", password);

        // 查询
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName, userLoginDTO.getNickName());
        User user = userService.getOne(queryWrapper);

        // 校验
        if (user == null) {
            return R.error("用户不存在！");
        }
        if (!user.getPassword().equals(password)) {
            return R.error("密码错误！");
        }
        if (user.getStatus() == 0) {
            return R.error("用户已被禁用，请联系管理员");
        }
//        if (!user.getJob().equals("1")) {
//            return R.error("对不起，但您不是管理员！"); // 区别仅这里
//        }

        // 登录成功
        //自定义信息
        Map<String , Object> claims = new HashMap<>();
        claims.put("id", user.getId());
        claims.put("username", user.getNickName());
        claims.put("name", user.getName());

        //使用JWT工具类，生成身份令牌
        String token = JwtUtils.generateJwt(claims);

        UserLoginVO userLoginVO = new UserLoginVO();
        userLoginVO.setId(user.getId());
        userLoginVO.setNickName(user.getNickName());
        userLoginVO.setToken(token);

        // 给前端相应结果，把用户的token给前端，要求前端每次请求时带上token
        return R.success(userLoginVO);
    }


    /**
     * 员工数据条件分页查询
     *
     * @param page     当前页
     * @param pageSize 每页大小
     * @param name     员工姓名
     * @param gender   性别
     * @param begin    入职时间
     * @param end      离职时间
     * @return PageBean对象
     */
    @GetMapping("/page")
    @ApiOperation("用户分页查询")
    public R<Page> page(@RequestParam(defaultValue = "1") Integer page,
                        @RequestParam(defaultValue = "10") Integer pageSize,
                        String name,
                        @ApiParam(value = "性别：1：男 2：女") Short gender,
                        @ApiParam(value = "查询开始时间，格式：yyyy-MM-dd", defaultValue = "2023-10-29")
                        @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate begin,
                        @ApiParam(value = "查询结束时间，格式：yyyy-MM-dd", defaultValue = "2023-10-31")
                        @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate end) {
        // log.info("员工分页查询的参数：page:{},pageSize:{},name:{},gender{}, begin{}, end{}", page, pageSize, name, gender, begin, end);

        //构造分页构造器
        Page pageInfo = new Page(page, pageSize);
        //条件限定
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.like(StringUtils.isNotEmpty(name), User::getName, name)
                .eq((gender != null), User::getGender, gender)
                .ge((begin != null), User::getCreateTime, begin)
                .le((end != null), User::getCreateTime, end)
                .select(User.class, i -> !i.getProperty().equals("password")); // 排除password字段

        //排序
        queryWrapper.orderByAsc(User::getId);
        //执行
        userService.page(pageInfo, queryWrapper);
        return R.success(pageInfo);
    }

    /**
     * 查询用户的个人信息
     *
     * @return
     */
    @GetMapping("/me")
    @ApiOperation("用户个人信息")
    public R<User> me() {
        // 拿到当前登录的用户的id
        Map<String , Object> claims = ThreadLocalUtil.get();
        Integer userId = (Integer) claims.get("id");

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, userId);
        User one = userService.getOne(queryWrapper);

        if (one == null) {
            return R.error("发生错误");
        }

        return R.success(one);
    }

    @PutMapping()
    @ApiOperation("根据id修改")
    public R<String> update(@RequestBody UserDTO userDTO) {
        // 好像只能拿一次！！？
//        Map<String , Object> claims = ThreadLocalUtil.get();
//        Integer userId = (Integer) claims.get("id");
//        String username = claims.get("username");


        String token = request.getHeader("token");
        Map<String, Object> claims = JwtUtils.parseJWT(token);
        Integer userId = (Integer) claims.get("id");

        User one = userService.getById(userId);
        BeanUtils.copyProperties(userDTO, one);
        System.out.println(one);
        userService.updateById(one);

        return R.success("更新成功！");
    }
}
